.\" This man page is Copyright (C) 2010 Lennert Buytenhek.
.\" Permission is granted to distribute possibly modified copies
.\" of this page provided the header is included verbatim,
.\" and in case of nontrivial modification author and date
.\" of the modification is added to the header.
.TH iv_work 3 2010-09-14 "ivykis" "ivykis programmer's manual"
.SH NAME
IV_WORK_POOL_INIT, iv_work_pool_create, iv_work_pool_put, IV_WORK_ITEM_INIT, iv_work_pool_submit_work \- ivykis
worker thread management
.SH SYNOPSIS
.B #include <iv_work.h>
.sp
.nf
struct iv_work_pool {
        int             max_threads;
        void            *cookie;
        void            (*thread_start)(void *cookie);
        void            (*thread_stop)(void *cookie);
};

struct iv_work_item {
        void            *cookie;
        void            (*work)(void *cookie);
        void            (*completion)(void *cookie);
};
.fi
.sp
.BI "void IV_WORK_POOL_INIT(struct iv_work_pool *" this ");"
.br
.BI "int iv_work_pool_create(struct iv_work_pool *" this ");"
.br
.BI "int iv_work_pool_put(struct iv_work_pool *" this ");"
.br
.BI "void IV_WORK_ITEM_INIT(struct iv_work_item *" work ");"
.br
.BI "int iv_work_pool_submit_work(struct iv_work_pool *" this ", struct iv_work_item *" work ");"
.br
.SH DESCRIPTION
Calling
.B iv_work_pool_create
on a
.B struct iv_work_pool
object previously initialised by
.B IV_WORK_POOL_INIT
creates a pool of worker threads that can be used to offload CPU
intensive tasks to, so as to prevent negatively influencing event
handling latency in the calling thread, and to enable the use of
multiple host CPUs for CPU intensive tasks.
.PP
.B iv_work
dynamically adjusts the number of threads in the pool to the amount
of work there is to do.  The
.B ->max_threads
member of
.B struct iv_work_pool
specifies the maximum number of threads that will be created in this
pool.
.PP
Calling
.B iv_work_pool_submit_work
on a
.B struct iv_work_item
object previously initialised by
.B IV_WORK_ITEM_INIT
submits a work item to a pool.  The
.B ->work
member of
.B struct iv_work_item
specifies the function that will be called in one of the worker
threads in the pool specified by
.B ->this,
with
.B ->cookie
as its sole argument.  When the work function has completed,
.B iv_work
will call the
.B ->completion
callback to indicate this, also with
.B ->cookie
as its sole argument, in the thread that
.B iv_work_pool_create
was called in for this pool object.
.PP
As a special case, calling
.B iv_work_pool_submit_work
with a
.B NULL
work pool pointer will cause the work item to be processed in the local
thread, from an
.BR iv_task (3)
callback.
.PP
If the
.B ->thread_start
function pointer specified in
.B struct iv_work_pool
is not NULL, it will be called upon creation of a new worker thread,
in the context of the created worker thread, with
.B ->cookie
as its sole argument.  Calls to
.B ->thread_start
are not explicitly serialised, which should be kept in mind when
manipulating state shared between threads from within that callback
function.
.PP
Similarly, if
.B iv_work
decides to terminate a worker thread, for example due to inactivity,
.B ->thread_stop
will be called in the context of the terminating thread, with
.B ->cookie
as its sole argument.  Calls to
.B ->thread_stop
are also not explicitly serialised.
.PP
.B iv_work_pool_submit_work
can only be called from the thread that
.B iv_work_pool_create
for this pool object was called in.
.PP
There is no way to cancel submitted work items.
.PP
There is no guaranteed order, FIFO or otherwise, between different
work items submitted to the same worker thread pool.
.PP
When the user has no more work items to submit to the pool, its
reference to the pool can be dropped by calling
.B iv_work_pool_put.
.PP
If there are still pending or running work items assigned to this pool
when
.B iv_work_pool_put
is called, those work items will not be canceled, but will be allowed
to run to completion, and their
.B ->completion
callbacks will be called as usual.  A similar thing holds for the
.B ->thread_start
and
.B ->thread_stop
callbacks -- they can also still be called after
.B iv_work_pool_put
returns.  Even so, the memory corresponding to the
.B struct iv_work_pool
can immediately be freed or reused by the user upon return of the
.B iv_work_pool_put
call.
.PP
Internally,
.B iv_work
uses
.BR iv_thread (3)
for its thread management.
.PP
.SH "SEE ALSO"
.BR ivykis (3),
.BR iv_thread (3)
